<template>
  <div>

    <div class="container">
      <div class="handle-box">
        <el-select
          v-model="query.hotelName"
          placeholder="请选择酒店名称"
          filterable
          clearable
          style="width: 200px;" class="handle-input mr10"
        >
          <el-option
            v-for="hotel in hotels"
            :key="hotel.hotelId"
            :label="hotel.hotelName"
            :value="hotel.hotelName"
          />
        </el-select>
        <el-select
          v-model="query.userName"
          placeholder="请选择参会者姓名"
          filterable
          clearable
          style="width: 200px;" 
          class="handle-input mr10"
        >
          <el-option
            v-for="user in users"
            :key="user.participantId"
            :label="user.fullName"
            :value="user.fullName"
          />
        </el-select>
        <el-input v-model="query.roomNumber" clearable placeholder="房间号" style="width: 200px;" class="handle-input mr10"></el-input>
        <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
        <el-button type="primary" icon="el-icon-plus" @click="addVisible = true">新增</el-button>
        <!-- ✅ 导入导出按钮 -->
        <!-- <el-button
          type="success"
          icon="el-icon-upload2"
          class="mr10"
          @click="$refs.excelInput.click()"
        >导入 Excel</el-button> -->
        <input
          type="file"
          ref="excelInput"
          style="display: none"
          accept=".xlsx, .xls"
          @change="importFromExcel"
        />
        <el-button
          type="warning"
          icon="el-icon-download"
          @click="exportToExcel"
        >导出 Excel</el-button>
        <el-button type="danger" icon="el-icon-delete" @click="handleBatchDelete" :disabled="multipleSelection.length === 0">批量删除</el-button>
      </div>

      <el-table
        :data="tableData"
        border
        class="table"
        ref="multipleTable"
        header-cell-class-name="table-header"
        @selection-change="handleSelectionChange"
      >
        <el-table-column
          type="selection"
          width="55">
        </el-table-column>
        <!-- <el-table-column prop="bookingId" label="预定标识"></el-table-column> -->
        <el-table-column label="酒店名称">
          <template slot-scope="scope">
            {{ scope.row.hotels && scope.row.hotels.hotelName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="参会者姓名">
          <template slot-scope="scope">
            {{ scope.row.participants && scope.row.participants.fullName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="身份证">
          <template slot-scope="scope">
            {{ scope.row.participants && scope.row.participants.idCardNumber || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="参会者性别">
          <template #default="{ row }">
            {{ row.participants && row.participants.gender === 0 ? '男' : row.participants && row.participants.gender === 1 ? '女' : '-' }}
          </template>
        </el-table-column>
        <el-table-column prop="roomNumber" label="房间号"></el-table-column>
        <el-table-column prop="checkInDate" label="入住日期" :formatter="formatDateTime"></el-table-column>
        <el-table-column prop="checkOutDate" label="退房日期" :formatter="formatDateTime"></el-table-column>
        <el-table-column label="操作" width="180" align="center">
          <template slot-scope="scope">
            <el-button
              type="text"
              icon="el-icon-edit"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
            <el-button
              type="text"
              icon="el-icon-delete"
              class="red"
              @click="handleDelete(scope.row.bookingId)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination">
        <el-pagination
          background
          layout="total, prev, pager, next"
          :current-page="query.pageIndex"
          :page-size="query.pageSize"
          :total="pageTotal"
          @current-change="handlePageChange"
        ></el-pagination>
      </div>
    </div>

    <!-- 编辑弹出框 -->
    <el-dialog title="编辑" :visible.sync="editVisible" width="30%">
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        label-width="90px"
      >
        <el-form-item label="酒店名称" prop="hotels.hotelName">
          <el-input v-model="form.hotels.hotelId" placeholder="酒店ID" v-show="false" />
          <el-input v-model="form.hotelId" placeholder="酒店ID" v-show="false"/>
          <el-select
            v-model="form.hotels.hotelName"
            placeholder="请选择酒店名称"
            filterable
            clearable
            style="width: 100%;"
            @change="handleHotelChange"
          >
            <el-option
              v-for="hotel in hotels"
              :key="hotel.hotelId"
              :label="hotel.hotelName"
              :value="hotel.hotelName"
            />
          </el-select>
        </el-form-item>
      
        <el-form-item label="用户姓名" prop="participants.fullName">
          <el-input v-model="form.participantId" v-show="false"/>
          <el-input v-model="form.participants.participantId" v-show="false"/>
          <el-select
            v-model="form.participants.fullName"
            placeholder="请选择参会者姓名"
            filterable
            clearable
            style="width: 100%;"
            @change="handleParticipantChange"
          >
          <el-option
            v-for="user in users"
            :key="user.participantId"
            :label="user.fullName"
            :value="user.fullName"
          />
        </el-select>
        </el-form-item>
      
        <el-form-item label="房间号" prop="roomNumber">
          <el-input v-model="form.roomNumber" placeholder="请输入房间号" />
        </el-form-item>
      
        <el-form-item label="入住日期" prop="checkInDate">
          <el-date-picker
            v-model="form.checkInDate"
            type="datetime"
            placeholder="请选择入住日期"
            format="yyyy-MM-dd HH:mm"
            value-format="yyyy-MM-dd HH:mm:ss"
            style="width: 100%;"
          />
        </el-form-item>

        <el-form-item label="退房日期" prop="checkOutDate">
          <el-date-picker
            v-model="form.checkOutDate"
            type="datetime"
            placeholder="请选择退房日期"
            format="yyyy-MM-dd HH:mm"
            value-format="yyyy-MM-dd HH:mm:ss"
            style="width: 100%;"
          />
        </el-form-item>
      </el-form>
    
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelEdit">取 消</el-button>
        <el-button type="primary" @click="saveEdit">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 新增弹出框 -->
    <el-dialog title="新增" :visible.sync="addVisible" width="30%">
      <el-form
        ref="form"
        :model="addForm"
        :rules="rules"
        label-width="90px"
      >
      <el-form-item label="酒店名称" prop="hotels.hotelName">
        <el-input v-model="addForm.hotels.hotelId" placeholder="酒店ID" v-show="false"/>
        <el-input v-model="addForm.hotelId" placeholder="酒店ID" v-show="false" />
        <el-select
          v-model="addForm.hotels.hotelName"
          placeholder="请选择酒店名称"
          filterable
          clearable
          style="width: 100%;"
          @change="hotelName => handleHotelChange(hotelName, addForm)"
        >
          <el-option
            v-for="hotel in hotels"
            :key="hotel.hotelId"
            :label="hotel.hotelName"
            :value="hotel.hotelName"
          />
        </el-select>
      </el-form-item>
      
        <el-form-item label="用户姓名" prop="participants.fullName">
          <el-input v-model="addForm.participantId" v-show="false"/>
          <el-input v-model="addForm.participants.participantId" v-show="false"/>
                  <el-select
          v-model="addForm.participants.fullName"
          placeholder="请选择参会者姓名"
          filterable
          clearable
          style="width: 100%;"
          @change="fullName => handleParticipantChange(fullName, addForm)"
        >
          <el-option
            v-for="user in users"
            :key="user.participantId"
            :label="user.fullName"
            :value="user.fullName"
          />
        </el-select>
        </el-form-item>
      
        <el-form-item label="房间号" prop="roomNumber">
          <el-input v-model="addForm.roomNumber" placeholder="请输入房间号" />
        </el-form-item>
      
        <el-form-item label="入住日期" prop="checkInDate">
          <el-date-picker
            v-model="addForm.checkInDate"
            type="datetime"
            placeholder="请选择入住日期"
            format="yyyy-MM-dd HH:mm"
            value-format="yyyy-MM-dd HH:mm:ss"
            style="width: 100%;"
          />
        </el-form-item>

        <el-form-item label="退房日期" prop="checkOutDate">
          <el-date-picker
            v-model="addForm.checkOutDate"
            type="datetime"
            placeholder="请选择退房日期"
            format="yyyy-MM-dd HH:mm"
            value-format="yyyy-MM-dd HH:mm:ss"
            style="width: 100%;"
          />
        </el-form-item>
      </el-form>
    
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelAdd">取 消</el-button>
        <el-button type="primary" @click="saveAdd">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
import * as XLSX from 'xlsx';
import requests from '../utils/request'
import dayjs from 'dayjs';


export default {
    name: 'basetable',
    data() {
      return {
        query: {
            hotelName: '',
            userName: '',
            roomNumber: '',
            pageIndex: 1,
            pageSize: 30
        },
        tableData: [],
        multipleSelection: [],
        exportData: [],
        editVisible: false,
        addVisible: false,
        pageTotal: 0,
        form: {
          hotelId:null,
          hotels:{
            hotelId:null,
            hotelName: '',
          },
          participantId: null,
          participants: {
            participantId: null,
            fullName: ''
          },
          roomNumber: '',
          checkInDate: null,
          checkOutDate: null
        },
        hotels:{},
        users:{},
        addForm: {
          hotelId: '',     // 用于提交给后端的主键字段
      participantId: '',
      roomNumber: '',
      checkInDate: '',
      checkOutDate: '',
          hotels: {
            hotelName: '',
            hotelId: ''
          },
          participants: {
            fullName: '',
            participantId: ''
          }
        },
        idx: -1,
        id: -1,
        rules: {
          "hotels.hotelName": [
            { required: true, message: '酒店名称不能为空', trigger: 'change' }
          ],
          "participants.fullName": [
            { required: true, message: '参会者姓名不能为空', trigger: 'change' }
          ],
          roomNumber: [
            { required: true, message: '房间号不能为空', trigger: 'blur' }
          ],
          checkInDate: [
            { required: true, message: '请选择入住日期', trigger: 'change' }
          ],
          checkOutDate: [
            { required: true, message: '请选择退房日期', trigger: 'change' }
          ]
        }
      };
    },
    created() {
       this.loading()
    },
    methods: {
      //加载数据
      loading() {
        requests.get("/accommodationBookings/pageSelect", {
          page: this.query.pageIndex,
          size: this.query.pageSize,
          hotelName: this.query.hotelName,
          userName: this.query.userName,
          roomNumber: this.query.roomNumber
        }).then(res=>{
          this.pageTotal = res.total,
          this.tableData = res.data
        });
        requests.get("/hotels/selectAllHotelName").then(res=>{
          this.hotels = res
        })
        requests.get("/participants/selectAllParticipant").then(res=>{
          this.users = res
        })
      },
      // 触发搜索按钮
      handleSearch() {
          this.loading();
      },
      //时间格式化
      formatDateTime(row, column, cellValue) {
        if (!cellValue) return '';
        const date = new Date(cellValue);
        const pad = n => n.toString().padStart(2, '0');
        return `${date.getFullYear()}/${pad(date.getMonth() + 1)}/${pad(date.getDate())} ` +
               `${pad(date.getHours())}:${pad(date.getMinutes())}`;
      },
      // 删除操作
      handleDelete(row) {
        // 二次确认删除
        this.$confirm('确定要删除吗？', '提示', {
            type: 'warning'
        })
            .then(() => {
                requests.delete("/accommodationBookings/delById",{
                  bookingId: row
                }).then(res=>{
                  this.$message.success(res);
                  this.loading()
                })
            })
      },
      // 编辑操作
      handleEdit(row) {
        // 安全深拷贝 row 对象，避免响应式污染
        const newForm = JSON.parse(JSON.stringify(row));
      
        // 时间字段转换（Element UI 需要 'yyyy-MM-dd HH:mm:ss' 字符串）
        if (newForm.checkInDate) {
          newForm.checkInDate = dayjs(newForm.checkInDate).format('YYYY-MM-DD HH:mm:ss');
        }
        if (newForm.checkOutDate) {
          newForm.checkOutDate = dayjs(newForm.checkOutDate).format('YYYY-MM-DD HH:mm:ss');
        }
      
        // 赋值给表单
        this.form = newForm;
        this.editVisible = true;
      },
      // 取消编辑
      cancelEdit() {
        // 失去当前聚焦
        document.activeElement && document.activeElement.blur();
      
        this.editVisible = false;
        // 重置表单（如果需要）
        this.$refs.form.resetFields();
      },
      // 保存编辑
      saveEdit() {
        // 先校验表单
        this.$refs.form.validate(valid => {
          if (!valid) {
            // 校验失败，不提交
            return;
          }
          // 校验成功，调用接口
          requests.post("/accommodationBookings/edit", this.form)
            .then(res => {
              this.$message.success(res);  // 用 success 提示更合适
              this.editVisible = false;    // 请求成功后关闭弹窗
              this.loading();              // 刷新数据
            })
        });
      },
      // 分页导航
      handlePageChange(val) {
          this.query.pageIndex = val
          this.loading()
      },
        // 单选、多选改变时调用
      handleSelectionChange(val) {
        this.multipleSelection = val;
      },
      // 批量删除
      handleBatchDelete() {
        if (this.multipleSelection.length === 0) {
          this.$message.warning('请选择要删除的酒店');
          return;
        }
      
        this.$confirm(`确定删除这 ${this.multipleSelection.length} 项吗？`, '提示', {
          type: 'warning'
        })
          .then(() => {
            const ids = this.multipleSelection.map(item => item.bookingId);
            requests.post('/accommodationBookings/delByIds', ids)  // ✅ 注意这里直接传数组
              .then(res => {
                this.$message.success(res);
                this.loading(); // 重新加载表格
              })

          })

      },
      //新增操作
      handleAdd(row) {
        this.addForm = row;
        this.addVisible = true;
      },
      // 取消操作
      cancelAdd() {
        // 失去当前聚焦
        document.activeElement && document.activeElement.blur();
      
        this.editVisible = false;
        // 重置表单（如果需要）
        this.$refs.addForm.resetFields();
      },
      // 保存操作
      saveAdd() {
        // 先校验表单
        this.$refs.form.validate(valid => {
          if (!valid) {
            // 校验失败，不提交
            return;
          }
        
          // 校验成功，调用接口
          requests.post("/accommodationBookings/add", this.addForm)
            .then(res => {
              this.$message.success(res);  // 用 success 提示更合适
              this.addVisible = false;    // 请求成功后关闭弹窗
              this.loading();              // 刷新数据
            })

        });
      },
      // 通用：监听酒店名称变更
      handleHotelChange(hotelName, targetForm = this.form) {
        const selected = this.hotels.find(h => h.hotelName === hotelName);
        if (selected) {
          targetForm.hotels.hotelId = selected.hotelId;
          targetForm.hotelId = selected.hotelId;
        } else {
          targetForm.hotels.hotelId = '';
          targetForm.hotelId = '';
        }
      },
      // 通用：监听参会者名称变更
      handleParticipantChange(fullName, targetForm = this.form) {
        const selected = this.users.find(user => user.fullName === fullName);
        if (selected) {
          targetForm.participants.participantId = selected.participantId;
          targetForm.participantId = selected.participantId;
        } else {
          targetForm.participants.participantId = '';
          targetForm.participantId = '';
        }
      },
      //导出
      exportToExcel() {
        requests.get("/accommodationBookings/exportBookingInfor").then(res => {
          // 通用日期解析函数
          const parseDateValue = (value) => {
            if (!value) return null;
            let date;
            if (typeof value === 'number') {
              date = new Date(value < 1e12 ? value * 1000 : value);
            } else if (typeof value === 'string') {
              const num = Number(value);
              if (!isNaN(num) && /^\d+$/.test(value.trim())) {
                date = new Date(num < 1e12 ? num * 1000 : num);
              } else {
                const parsed = Date.parse(value);
                if (isNaN(parsed)) return null;
                date = new Date(parsed);
              }
            } else {
              return null;
            }
            if (isNaN(date.getTime()) || date.getTime() <= 0) return null;
            date.setSeconds(0, 0); // 秒和毫秒置 0
            return date;
          };
        
          // 转换导出数据格式
          let exportData = res.map(row => {
            const checkInDate = parseDateValue(row.checkInDate);
            const checkOutDate = parseDateValue(row.checkOutDate);
            return {
              // 预定标识: String(row.bookingId),
              // 酒店标识: String(row.hotelId),
              酒店名称: row.hotels && row.hotels.hotelName ? row.hotels.hotelName : '',
              // 用户标识: String(row.participantId),
              用户姓名: row.participants && row.participants.fullName ? row.participants.fullName : '',
              身份证: row.participants && row.participants.idCardNumber ? String(row.participants.idCardNumber) : '',
              用户性别: row.participants && row.participants.gender === 1 ? '女' : row.participants && row.participants.gender === 0 ? '男' : '-',
              房间号: String(row.roomNumber),
              入住日期: checkInDate || '',
              退房日期: checkOutDate || ''
            };
          });
          
          // 如果没有任何数据，也保留表头结构
          if (exportData.length === 0) {
            exportData.push({
              // 预定标识: '',
              // 酒店标识: '',
              酒店名称: '',
              // 用户标识: '',
              用户姓名: '',
              身份证: '',
              用户性别: '',
              房间号: '',
              入住日期: '',
              退房日期: ''
            });
          }
          // 创建工作表
          const ws = XLSX.utils.json_to_sheet(exportData, { dateNF: 'yyyy/mm/dd hh:mm' });
        
          // 设置列宽
          ws['!cols'] = [
            // { wch: 12 }, // 预定标识
            // { wch: 12 }, // 酒店标识
            { wch: 30 }, // 酒店名称
            // { wch: 30 }, // 用户标识
            { wch: 15 }, // 用户姓名
            { wch: 30 }, //身份证
            { wch: 10 }, // 用户性别
            { wch: 10 }, // 房间号
            { wch: 30 }, // 入住日期
            { wch: 30 }  // 退房日期
          ];
        
          const header = Object.keys(exportData[0] || {});
          const keys = Object.keys(ws);
        
          // 格式化日期列
          ['入住日期', '退房日期'].forEach(colName => {
            const dateIndex = header.indexOf(colName);
            if (dateIndex >= 0) {
              const colLetter = String.fromCharCode(65 + dateIndex);
              keys.forEach(key => {
                if (key.startsWith(colLetter) && key !== `${colLetter}1`) {
                  const cell = ws[key];
                  if (cell && (cell.v instanceof Date || !isNaN(Date.parse(cell.v)))) {
                    if (!(cell.v instanceof Date)) {
                      const d = new Date(cell.v);
                      d.setSeconds(0, 0);
                      cell.v = d;
                    }
                    cell.t = 'd';
                    cell.z = 'yyyy/mm/dd hh:mm';
                  }
                }
              });
            }
          });
        
          // 设置“预定标识”列为文本
          const serialIndex = header.indexOf('预定标识');
          if (serialIndex >= 0) {
            const serialColLetter = String.fromCharCode(65 + serialIndex);
            keys.forEach(key => {
              if (key.startsWith(serialColLetter) && key !== `${serialColLetter}1`) {
                const cell = ws[key];
                if (cell) {
                  cell.t = 's';
                  cell.z = '@';
                }
              }
            });
          }
        
          // 创建并导出工作簿
          const wb = XLSX.utils.book_new();
          XLSX.utils.book_append_sheet(wb, ws, '住宿数据');
          XLSX.writeFile(wb, '住宿列表.xlsx');
        })
      },
      //导入
      importFromExcel(e) {
        const file = e.target.files[0];
        if (!file) return;
      
        const reader = new FileReader();
  reader.onload = (event) => {
    const data = new Uint8Array(event.target.result);
    const workbook = XLSX.read(data, { type: 'array' });
    const firstSheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[firstSheetName];

    // 提取数据为 JSON
    let excelData = XLSX.utils.sheet_to_json(worksheet, { raw: false });
    excelData = excelData.filter(row =>
      Object.values(row).some(v => v != null && String(v).trim() !== '')
    );

    if (excelData.length === 0) {
      this.$message.warning('Excel 中无有效数据，无法导入');
      this.$refs.excelInput.value = '';
      return;
    }

    // 时间字符串转格式 yyyy-MM-dd HH:mm:ss
    const parseExcelDateToStr = (str) => {
      if (!str || typeof str !== 'string') return null;
      const s = str.trim().replace(/\//g, '-').replace(/\.0+$/, '');
      let timestamp = Date.parse(s);
      if (isNaN(timestamp)) {
        const parts = s.split(' ');
        if (parts.length === 2) {
          timestamp = Date.parse(parts[0] + 'T' + parts[1]);
        }
      }
      if (isNaN(timestamp)) return null;
      const date = new Date(timestamp);
      if (isNaN(date.getTime())) return null;
      const pad = n => n.toString().padStart(2, '0');
      return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:00`;
    };

    // 数据映射与初步校验
    const mappedData = excelData.map((row, idx) => {
      const bookingId = Number(row['预定标识']);
      const hotelId = Number(row['酒店标识']);
      const participantId = Number(row['用户标识']);
      const roomNumber = Number(row['房间号']);
      if ([bookingId, hotelId, participantId, roomNumber].every(isNaN)) {
        console.warn(`第 ${idx + 2} 行无有效数字字段，跳过`, row);
        return null;
      }

      return {
        bookingId: isNaN(bookingId) ? null : bookingId,
        hotelId: isNaN(hotelId) ? null : hotelId,
        hotels: {
          hotelName: row['酒店名称'] || null
        },
        participantId: isNaN(participantId) ? null : participantId,
        participants: {
          fullName: row['用户姓名'] || null,
          gender: row['用户性别'] === '女' ? 1 : row['用户性别'] === '男' ? 0 : null
        },
        roomNumber: isNaN(roomNumber) ? null : roomNumber,
        checkInDate: parseExcelDateToStr(row['入住日期']),
        checkOutDate: parseExcelDateToStr(row['退房日期'])
      };
    }).filter(item => item !== null);

    if (mappedData.length === 0) {
      this.$message.warning('所有行均不符合导入要求，未生成可提交的数据');
      this.$refs.excelInput.value = '';
            return;
          }
        
          // 拆分有效与无效数据
          const validData = [];
          let invalidCount = 0;
          for (const item of mappedData) {
            if (
              item.bookingId != null &&
              item.hotelId != null &&
              item.participantId != null &&
              item.roomNumber != null
            ) {
              validData.push(item);
            } else {
              invalidCount++;
            }
          }
        
          // if (validData.length === 0) {
          //   this.$message.warning(`所有 ${invalidCount} 行字段不完整或日期解析失败，未导入任何数据`);
          //   this.$refs.excelInput.value = '';
          //   return;
          // }
        
          // if (invalidCount > 0) {
          //   this.$message.warning(`有 ${invalidCount} 行数据不完整或日期解析失败，仅导入 ${validData.length} 行`);
          // }
        
          // 提交数据
          requests.post('/accommodationBookings/importBookingInfor', validData)
            .then(response => {
              this.$message.success((response && response.data) || 'Excel 导入成功');
              this.loading();
            })
          this.$refs.excelInput.value = '';
        };
      
        reader.readAsArrayBuffer(file);
      }
    }
};
</script>

<style scoped>
.handle-box {
    margin-bottom: 20px;
}

.handle-select {
    width: 120px;
}

.handle-input {
    width: 300px;
    display: inline-block;
}
.table {
    width: 100%;
    font-size: 14px;
}
.red {
    color: #ff0000;
}
.mr10 {
    margin-right: 10px;
}
.table-td-thumb {
    display: block;
    margin: auto;
    width: 40px;
    height: 40px;
}
</style>
